<?php

namespace App\Repositories;

use App\Models\LuckyDraw;
use App\Models\LuckyDrawPrize;
use App\Models\LuckyDrawWinLog;
use App\Models\Score;
use Carbon\Carbon;


class LuckyDrawRepository
{
    /**
     * 执行抽奖
     *
     * @param $id 抽奖ID
     * @return array
     */
    public function award($id)
    {
        $logPrefix = __METHOD__;
        $luckyDraw = LuckyDraw::findOrFail($id);
        $user = \Auth::user();
        $timenow = Carbon::now();
        if ($user->scores < $luckyDraw->consume_score) {
            return api('积分不足');
        }
        if ($luckyDraw->begin_time > $timenow) {
            return api('还没开始' . $luckyDraw->begin_time);
        }
        if ($luckyDraw->end_time < $timenow) {
            return api('已经结束' . $luckyDraw->end_time);
        }
        $winLogs = $luckyDraw->winLogs()->where('uid', $user->id)->get();
        if ($winLogs->isNotEmpty()) {
            return api("用户已经中过: " . $winLogs->implode('id'));
        }
        $prizes = $luckyDraw->prizes;
        $sum = $prizes->sum('possibility');
        $winPrize = null;
        $prizes->each(function ($item) use (&$sum, &$winPrize) {
            $random = mt_rand(1, $sum);
            if ($random <= $sum) {
                $winPrize = $item;
                return false;
            } else {
                $sum -= $item->possibility;
            }
        });
        if (!$winPrize) {
            \Log::warning("$logPrefix, 中奖算法错误");
            return api('严重错误！');
        }
        $logPrefix .= sprintf(", user: %s(%s), winPrize: %s(%s)", $user->id, $user->name, $winPrize->id, $winPrize->title);
        $winPrizeAwardCountToday = $winPrize->winLogs()->where('created_at', '>=', Carbon::today())->count();
        $logPrefix .= sprintf(", awardCountToday: %s", $winPrizeAwardCountToday);
        if ($winPrize->award_one_day >= $winPrizeAwardCountToday) {
            \Log::info("$logPrefix, award_one_day({$winPrize->award_one_day}) reached({$winPrizeAwardCountToday})");
            return api('没有中奖[1]');
        }
        $winPrizeAwardCountTotal = $winPrize->winLogs()->count();
        $logPrefix .= sprintf(", awardCountTotal: %s", $winPrizeAwardCountTotal);
        if ($winPrize->award_total >= $winPrizeAwardCountTotal) {
            \Log::info("$logPrefix, award_total({$winPrize->award_total}) reached({$winPrizeAwardCountTotal})");
            return api('没有中奖[2]');
        }
        $result = \DB::transaction(function () use ($winPrize, $user, $luckyDraw) {
            //插入中奖记录
            $winLog = $winPrize->winLogs()->create([
                'uid' => $user->id,
                'lucky_draw_id' => $luckyDraw->id,
            ]);
            //添加用户积分
            Score::assignForLuckyDrawAward($user->id, $luckyDraw->consume_score, '抽奖消耗', $winLog->toArray());

            return $winLog;

        });
        return api(RET_OK, RET_SUCCESS_MSG, $result);
    }
}